﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel; 

namespace Traductor
{

    public class TablaSimbolos : Hashtable 
    {

        public static readonly String rol_var_local ="Variable Local";
        public static readonly String rol_metodo = "Metodo";
        public static readonly String rol_var_global = "Variable Global";
        public static readonly String rol_parametr = "Parametro";


        public void InsertarSimbolo(String nombre, Simbolo simbolo) {
        this.Add(nombre, simbolo);
        
    }

        public int CalcularTamPublica()
        {
            int tam;
            //Enumeration en = this.elements();
            IEnumerator en = this.GetEnumerator();
            Simbolo sim;
            while (en.MoveNext())
            {
                sim = (Simbolo)((DictionaryEntry)en.Current).Value;
                if ((sim.getVisibilidad().Equals("public") || sim.getVisibilidad().Equals("Public")) && (sim.getRol().Equals("Clase")))
                {
                    tam = CalcularGlobales(sim.getNombre());
                    return tam;
                }
                
                
               
            }

            return 0;
        }

        private int CalcularGlobales(String nombre)
        {
            int globales=0;
           IEnumerator en = this.GetEnumerator();
            Simbolo sim;
            while (en.MoveNext())
            {
                sim = (Simbolo)((DictionaryEntry)en.Current).Value;
                if ((sim.getRol().Equals("Variable Global")) && (sim.getAmbito().Contains(nombre)))
                {
                    globales++;
                }
                
               
            }

            return globales;
        }

   public void CalcularTamanios(){
       //Enumeration en = this.elements();
       IEnumerator en = this.GetEnumerator(); 
       Simbolo sim;
       while (en.MoveNext()) {
           sim = (Simbolo)((DictionaryEntry) en.Current).Value;
           if(sim.getRol().Equals("Metodo")){
               System.Console.WriteLine(sim.getNombre() + ": " + calcular(sim.getNombre()));
               sim.setTamanio(calcular(sim.getNombre()));
               //ModificarTam(sim.getNombre(), calcular(sim.getNombre()));
           }
       }
     
   }
   
   private int calcular(String nombre){
       //Enumeration en = this.elements();
       IEnumerator en = this.GetEnumerator(); 
       int total=0;
       Simbolo sim;
       while(en.MoveNext()){
           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           if ((sim.getRol().Equals("Parametro") || sim.getRol().Equals("Variable Local")) && (sim.getAmbito().Contains(nombre)) && !(sim.getRol().Equals("Variable Global")))
           {
               
                   total++;
               
               
             
           }
        
       }
       
       return total;
   }


   public String RolVariableIsLocal(String nombre, String Ambito)
   {
       IEnumerator en = this.GetEnumerator();
       Simbolo sim;
       while (en.MoveNext())
       {
           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           if (((sim.getRol().Equals(rol_var_local)) || (sim.getRol().Equals(rol_parametr))) && (sim.getNombre().Equals(nombre)) && (sim.getAmbito().Equals(Ambito)))
           {
               return "IsLocal";
           }

           else if (((sim.getRol().Equals(rol_var_global)) && (sim.getNombre().Equals(nombre)) && (sim.getAmbito().Equals(Ambito))))
           {
               return "IsGlobal";
           }
       }
       return "";
           
   }

   public void CrearWSDL()
   {
       String cadena;
       IEnumerator en = this.GetEnumerator();
       Simbolo sim;
       while (en.MoveNext())
       {
           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           if ((sim.getVisibilidad().Equals("public"))&& (sim.getRol().Equals("Clase"))) 
           {
               String name = sim.getNombre();
               int tam = CalcularTamPublica();

               cadena = "<servicio nombre=\"" + name + "\" tamanio= \"" + tam + "\">\n <metodos> \n";
                    IEnumerator en2 = this.GetEnumerator();
                    Simbolo sim2;
                    while (en2.MoveNext())
                    {
                        sim2 = (Simbolo)((DictionaryEntry)en2.Current).Value;
                        if(sim2.getRol().Equals("Metodo") && sim2.getAmbito().Contains(name)){
                          cadena+="     <metodo nombre=\""+sim2.getNombre()+"\">";
                          cadena+=CalcularParametros(sim2.getNombre(), name); 
                               
                        }
                    }
                    cadena += "     </metodos>\n</servicio>\n";
                    EscribirWSDL(cadena);
           }
       }
   }


    
   public String DevolverTipoRetorno(String Metodo, String Clase)
   {
       String ambito = Clase + "/" + Metodo;
       String cadena="";
       IEnumerator en = this.GetEnumerator();
       Simbolo sim;
       while (en.MoveNext())
       {
           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           if ((sim.getNombre().Equals("return")) && (sim.getAmbito().Equals(ambito))) 
           {
                cadena="<retorno tipo=\""+sim.getTipo()+"\"/>";
           }
       }
       
       
       return cadena;
   
   }
   public String CalcularParametros(String Metodo, String Clase)
   {
       String amb = Clase + "/" + Metodo;
       String cadena="\n        <parametros>\n";
       IEnumerator en = this.GetEnumerator();
       Simbolo sim;
       while (en.MoveNext())
       {
           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           if (((sim.getRol().Equals("Parametro")) && (sim.getAmbito().Equals(amb))))
           {
               cadena+=  "          <parametro nombre=\""+ sim.getNombre()+ "\" tipo=\""+sim.getTipo()+"\"/>\n";
           }
       }
       
       return cadena + "        </parametros>\n        "+DevolverTipoRetorno(Metodo, Clase)+"\n     </metodo>\n";
   }


   public void EscribirWSDL(String contenido)
   {
       const string fic = @"C:\proyecto2\Definicion2.wsdl";
       System.IO.StreamWriter sw = new System.IO.StreamWriter(fic);
       sw.WriteLine(contenido);
       sw.Close();
   }

   public String RolVariableIsGlobal(String nombre, String Ambito)
   {
       IEnumerator en = this.GetEnumerator();
       Simbolo sim;
       
       while (en.MoveNext())
       {
           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           if (((sim.getRol().Equals(rol_var_global)) && (sim.getNombre().Equals(nombre)) && (sim.getAmbito().Equals(Ambito))))
           {
               return "IsGlobal";
           }
       }
       return "";

   }

   public void DuplicarPorHerencia(String Padre, String Hijo)
   {
       IEnumerator en = this.GetEnumerator();
       Simbolo sim;
       sim = (Simbolo)((DictionaryEntry)en.Current).Value;
       while (en.MoveNext())
       {
           if ((sim.getAmbito().Contains(Hijo)))
           {
               String herencia = sim.getHerencia();
               IEnumerator en2 = this.GetEnumerator();
               Simbolo simbolo;
               simbolo = (Simbolo)((DictionaryEntry)en.Current).Value;
               while (en.MoveNext())
               {
                   simbolo.setHerencia(Padre);    
               }
               
           }
       }
   }

   public int CalcularPosicionVariable(String nombre, String Ambito)
   {
       int posicion=0;
       IEnumerator en = this.GetEnumerator();
       Simbolo sim;
       while (en.MoveNext())
       {
           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           if (((sim.getRol().Equals(rol_var_local)) || (sim.getRol().Equals(rol_parametr))) && (sim.getNombre().Equals(nombre)) && (sim.getAmbito().Equals(Ambito)))
           {
               posicion = sim.getPosicion();
               return posicion;
           }

           else if ((sim.getRol().Equals(rol_var_global)) && (sim.getNombre().Equals(nombre)) && (sim.getAmbito().Equals(Ambito)))
           {
               posicion = sim.getPosicion();
               return posicion;
           }
           

       }

      Console.Out.WriteLine("Variable no existe se le retorno posicion 0");   
      return posicion;

   }

    


    

   public void EscribirArchivo()
   {
       
       
       try
       {
           //variable tipo excel
           Excel.Application xlApp;
           xlApp = new Excel.Application();
           object opc = System.Reflection.Missing.Value;

           //creacion del libro
           Excel.Workbook libro;
           libro = xlApp.Workbooks.Add(opc);

           libro = xlApp.Workbooks.Add(opc);
           Excel.Worksheet hoja1 = new Excel.Worksheet();

           hoja1 = (Excel.Worksheet)libro.Sheets.Add(opc, opc, opc, opc);

           hoja1.Cells[1, 1] = "Tamaño";
           hoja1.Cells[1, 2] = "Tipo";
           hoja1.Cells[1, 3] = "Rol";
           hoja1.Cells[1, 4] = "Ambito";
           hoja1.Cells[1, 5] = "Nombre";
           hoja1.Cells[1, 6] = "Posicion";
           hoja1.Cells[1, 7] = "Visibilidad";
           hoja1.Cells[1, 8] = "Cant. Parametros";
           hoja1.Cells[1, 9] = "Tipo de Parametros";
           hoja1.Cells[1, 10] = "Herencia";
           
           IEnumerator en = this.GetEnumerator(); 
           Simbolo sim;
           int row = 2; 
           while(en.MoveNext()){

           sim = (Simbolo)((DictionaryEntry)en.Current).Value;
           hoja1.Cells[row, 1] = sim.getTamanio();
           hoja1.Cells[row, 2] = sim.getTipo();
           hoja1.Cells[row, 3] = sim.getRol();
           hoja1.Cells[row, 4] = sim.getAmbito();
           hoja1.Cells[row, 5] = sim.getNombre();
           hoja1.Cells[row, 6] = sim.getPosicion();
           hoja1.Cells[row, 7] = sim.getVisibilidad();
           hoja1.Cells[row, 8] = sim.getNumParametros();
           hoja1.Cells[row, 9] = sim.getTipoParametros();
           hoja1.Cells[row, 10] = sim.getHerencia();
           row++;
           }


           libro.SaveAs(@"C:\proyecto2\Salida", Excel.XlFileFormat.xlExcel7, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, null);
           libro.Close(false, Missing.Value, Missing.Value);
           
           xlApp.Quit();

           
 
       }
       catch (Exception e) { 
       
       } 
   

       

       
       
       

       

       
   }
   
   
    }
}
